import { type FileData, type UploadConfig, createMultipartUploadV2Task } from 'qiniu-js';
import { type UploadResponse, getQnUptokenAxios } from '@/api/upload';
import { getFileMd5BySlice } from '@/utils/file-md5';
import { myStrToJson } from '@/utils/data';

/**
 * 上传到七牛云
 */
export async function uploadQiNiu(data: {
  file: File;
  folder: string;
  onUploadProgress?: (res: { percent: number; size: number }) => void;
}): Promise<UploadResponse> {
  try {
    const { file, folder, onUploadProgress } = data;
    // 得到文件的md5
    const md5 = await getFileMd5BySlice(file);
    // 得到七牛云的上传 token
    const tokenRes = await getQnUptokenAxios({ md5, folder, fileName: file.name, fileType: file.type });
    // 开始上传
    const res: UploadResponse = await beginUploadQiNiu({ file, token: tokenRes.data, onUploadProgress });
    return Promise.resolve(res);
  } catch (err) {
    return Promise.reject(err);
  }
}

/**
 * 开始上传到七牛云
 */
function beginUploadQiNiu(data: { file: File; token: string; onUploadProgress?: (res: { percent: number; size: number }) => void }): Promise<UploadResponse> {
  return new Promise((resolve, reject) => {
    try {
      const { file, token, onUploadProgress } = data;
      const fileData: FileData = { type: 'file', data: file };
      const config: UploadConfig = {
        tokenProvider: () => Promise.resolve(token),
      };

      const uploadTask = createMultipartUploadV2Task(fileData, config);

      // 设置进度回调函数
      uploadTask.onProgress((progress) => {
        // 处理进度回调
        typeof onUploadProgress === 'function' && onUploadProgress({ percent: progress.percent, size: progress.size });
      });

      // 设置完成回调函数
      uploadTask.onComplete((result, _context) => {
        const res = (myStrToJson(result) || {}) as Record<string, string | undefined>;
        const newRes: UploadResponse = {
          ...res,
          width: typeof res.width === 'string' ? Number(res.width) : undefined,
          height: typeof res.height === 'string' ? Number(res.height) : undefined,
          size: typeof res.size === 'string' ? Number(res.size) : undefined,
        } as UploadResponse;
        // console.log('上传成功====', newRes, context);
        resolve(newRes);
      });

      // 设置错误回调函数
      uploadTask.onError((error) => {
        console.log('上传错误====', error);
        reject(error);
      });
      uploadTask.start();
    } catch (err) {
      reject(err);
    }
  });
}
